package com.heima.comment.service.impl;

import com.heima.comment.service.CommentRepayService;
import com.heima.comment.service.CommentService;
import com.heima.common.exception.CustException;
import com.heima.feigns.UserFeign;
import com.heima.model.behavior.pojos.ApLikesBehavior;
import com.heima.model.comment.dtos.CommentRepayDTO;
import com.heima.model.comment.dtos.CommentRepayLikeDTO;
import com.heima.model.comment.dtos.CommentRepaySaveDTO;
import com.heima.model.comment.pojos.ApComment;
import com.heima.model.comment.pojos.ApCommentRepay;
import com.heima.model.comment.pojos.ApCommentRepayLike;
import com.heima.model.comment.vos.ApCommentRepayVO;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.threadlocal.AppThreadLocalUtils;
import com.heima.model.user.pojos.ApUser;
import com.heima.tencentcloud.scan.ContentSecurityScan;
import com.heima.utils.common.string.KeywordFilterUtil;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.tms.v20201229.models.TextModerationResponse;
import org.springframework.beans.BeanUtils;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author XHui
 * @Since 2024/3/5 13:22
 * @Version 1.0
 */
@Service
public class CommentRepayServiceImpl implements CommentRepayService {

    @Resource
    private CommentService commentService;

    @Resource
    private MongoTemplate mongoTemplate;

    @Resource
    private UserFeign userFeign;

    @Override
    public ResponseResult loadCommentRepay(CommentRepayDTO dto) {
        // 1. 前置操作
        dto.tryCorrectParams();
        String commentId = dto.getCommentId();
        Integer size = dto.getSize();
        Date minDate = dto.getMinDate();
        // 1.1 获取用户行为
        ApUser user = AppThreadLocalUtils.getUser();

        // 2. 查询评论回复列表
        // 2.1 封装查询条件
        Query query = new Query(
                Criteria.where("commentId").is(commentId)
                        .and("authorId").is(user.getId())
                        .and("createdTime").lt(minDate)
        );
        query.limit(10);
        //query.with(Sort.by(Sort.Direction.DESC, "createdTime"));

        // 2.2 进行查询
        List<ApCommentRepay> commentRepays = mongoTemplate.find(query, ApCommentRepay.class);
        // 2.3 进一步封装ApCommentRepayVO
        List<ApCommentRepayVO> apCommentRepayVOs = commentRepays.stream().map(item -> {
            ApCommentRepayVO apCommentRepayVO = new ApCommentRepayVO();
            BeanUtils.copyProperties(item, apCommentRepayVO);
            if (item.getLikes() > 0) {
                //  2.3.1 点赞数大于0，表示已经点赞
                apCommentRepayVO.setOperation(ApLikesBehavior.Operation.LIKE.getValue());
            } else {
                //  2.3.2 点赞数等于0，表示未点赞
                apCommentRepayVO.setOperation(ApLikesBehavior.Operation.UNLIKE.getValue());
            }
            return apCommentRepayVO;
        }).collect(Collectors.toList());

        // 3.  封装返回结果
        return ResponseResult.okResult(apCommentRepayVOs);
    }

    @Resource
    private ContentSecurityScan contentSecurityScan;

    @Override
    public ResponseResult saveCommentRepay(CommentRepaySaveDTO dto) {

        // 1.  保存评论回复
        String commentId = dto.getCommentId();
        String replyContent = dto.getContent();
        Integer userId = AppThreadLocalUtils.getUser().getId();

        try {
            TextModerationResponse textModerationResponse = contentSecurityScan.textScan(replyContent);
            String[] keywords = textModerationResponse.getKeywords();
            replyContent = KeywordFilterUtil.filterKeywords(replyContent, keywords);

            // 1.1 根据评论id查询评论信息
            ApComment commentByIdDB = commentService.findCommentById(commentId);
            if(commentByIdDB == null){
                CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST, "评论不存在");
            }

            //1.2 根据userId查询用户名 by userFeign
            ResponseResult<ApUser> responseResult = userFeign.findUserById(userId);
            if (responseResult.getData() == null) {
                CustException.cust(AppHttpCodeEnum.REMOTE_SERVER_ERROR, "远程调用失败");
            }

            // 1.3 保存评论回复, 创建评论回复实体
            ApCommentRepay apCommentRepay = new ApCommentRepay();
            apCommentRepay.setAuthorId(userId);
            apCommentRepay.setAuthorName(responseResult.getData().getName());
            apCommentRepay.setCommentId(commentId);
            apCommentRepay.setContent(replyContent);
            apCommentRepay.setLikes(0);
            Date date = new Date();
            apCommentRepay.setCreatedTime(date);
            apCommentRepay.setUpdatedTime(date);

            // 2.  保存评论回复
            mongoTemplate.insert(apCommentRepay);
            // 3.   更新评论回复数量: +1
            commentByIdDB.setReply(commentByIdDB.getReply() + 1);
            mongoTemplate.save(commentByIdDB);

            // 4.  返回结果
            return ResponseResult.okResult();
        } catch (TencentCloudSDKException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public ResponseResult saveCommentRepayLike(CommentRepayLikeDTO dto) {
        // 1. 根据评论回复ID查询该评论回复是否存在
        String commentRepayId = dto.getCommentRepayId();
        Short isLike = dto.getOperation();

        ApUser loggedUser = AppThreadLocalUtils.getUser();
        // 1.1 查询评论回复实体
        ApCommentRepay commentRepayDB = findCommentRepayById(commentRepayId);
        if (commentRepayDB == null) {
            CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST, "该评论回复不存在");
        }

        // 2. 分析用户的 评论回复 点赞操作是否存在
        Query query = new Query(
                Criteria.where("commentRepayId")
                .is(commentRepayId)
                .and("authorId")
                .is(loggedUser.getId())
        );

        // 2.0 查询用户是否点过赞
        ApCommentRepayLike commentRepayLikeDB = mongoTemplate.findOne(query, ApCommentRepayLike.class);

        if (ApLikesBehavior.Operation.LIKE.getValue() == isLike
                && commentRepayLikeDB == null) {
            // 2.1 点赞评论，ap_comment_repay_like表中新增一条记录 (前提是用户没有点过赞)
            ApCommentRepayLike apCommentRepayLike = new ApCommentRepayLike();
            apCommentRepayLike.setCommentRepayId(commentRepayId);
            apCommentRepayLike.setAuthorId(loggedUser.getId());
            apCommentRepayLike.setOperation(isLike);
            mongoTemplate.save(apCommentRepayLike);

            // 2.2 评论已被点赞，评论的点赞数+1 -> ap_comment_repay
            commentRepayDB.setLikes(commentRepayDB.getLikes() + 1);

        } else if (ApLikesBehavior.Operation.UNLIKE.getValue() == isLike
                && commentRepayLikeDB != null) {
            //  2.2 取消点赞评论，ap_comment_like表中删除一条记录
            // 2.2.1 点赞数最小为0
            int newLikes = commentRepayDB.getLikes() - 1;
            if (newLikes < 0) {
                newLikes = 0;
            }
            commentRepayDB.setLikes(newLikes);
            // 2.3 删除当前用户对该评论的点赞记录
            mongoTemplate.remove(commentRepayLikeDB);

        } else {
            CustException.cust(AppHttpCodeEnum.DATA_NOT_ALLOW, "点赞/取消点赞操作行为不合法");
        }

        // 3. 更新评论表中的点赞数, 或 +1 或 -1
        commentRepayDB.setUpdatedTime(new Date());
        mongoTemplate.save(commentRepayDB);

        // 4. 返回 评论回复 点赞最终数量
        HashMap<String, Integer> data = new HashMap<>();
        data.put("likes", commentRepayDB.getLikes());
        return ResponseResult.okResult(data);
    }

    @Override
    public ApCommentRepay findCommentRepayById(String id) {
        Query query = new Query(Criteria.where("id").is(id));
        return mongoTemplate.findOne(query, ApCommentRepay.class);
    }
}
